home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / zmdm_src / common.c next >
C/C++ Source or Header  |  1988-06-26  |  34KB  |  1,416 lines

  1. /*
  2.  *                ACKNOWLEDGEMENTS
  3.  *
  4.  *    ZMDM was derived from rz/sz for Unix  posted by 
  5.  *    Chuck Forsberg (...!tektronix!reed!omen!caf ). We
  6.  *    thank him for his excellent code, and for giving
  7.  *    us permission to use and distribute his code and
  8.  *    documentation.
  9.  *
  10.  *    Atari St version by:
  11.  *        Jwahar Bammi
  12.  *            usenet: mandrill!bammi@{decvax,sun}.UUCP
  13.  *            csnet:  bammi@mandrill.ces.CWRU.edu
  14.  *            arpa:   bammi@mandrill.ces.CWRU.edu
  15.  *            CompuServe: 71515,155
  16.  */
  17.  
  18. #include "config.h"
  19.  
  20. #define IN_COMMON
  21.  
  22. /*
  23.  * -rev 08-17-86
  24.  * mode function and most of the rest of the system dependent
  25.  * stuff for rb.c and sb.c   This file is #included so the includer
  26.  * can set parameters such as HOWMANY.  See the main file (rz.c/sz.c)
  27.  * for compile instructions.
  28.  */
  29.  
  30. #ifdef DLIBS
  31. #include <string.h>
  32. #endif
  33.  
  34. #include "zmdm.h"
  35. #include "zmodem.h"
  36.  
  37. #ifndef Supexec
  38.         /* Some versions of osbind don't define Supexec */
  39. #define Supexec(X) xbios(38,X)
  40. #endif
  41.  
  42. #define CRCTABLE
  43.  
  44.         /* GLOBALS */
  45. int Zmodem;        /* ZMODEM protocol requested */
  46. int Nozmodem;    /* If invoked as "rb" */
  47. int Badclose;    /* Error on last close */
  48. int Batch;
  49. int Wcsmask;
  50. int Verbose;
  51. int Quiet;        /* overrides logic that would otherwise set verbose */
  52. int Lleft;        /* number of characters in linbuf */
  53. int Readnum;    /* Number of bytes to ask for in read() from modem */
  54. int Crcflg;
  55. int ForceBinary;        /* local binary force override for rz */
  56.  
  57. FILE *logf;
  58. FILE *STDERR;
  59. int vdebug;    /* set if RDEBUG or SDEBUG */
  60.  
  61. char secbuf[KSIZE];
  62. char linbuf[KSIZE];
  63. #if (MWC || MANX)            /* File i/o buffer */
  64. unsigned char *bufr;    /* In MWC or MANX it is lmalloc()'ed in main.c */
  65. #else
  66. #ifndef DYNABUF
  67. unsigned char bufr[BBUFSIZ];
  68. #else
  69. unsigned char *bufr;
  70. #endif /* DYNABUF */
  71. #endif
  72. int fout;
  73. int Lastrx;
  74. int Firstsec;
  75. int Eofseen;        /* indicates cpm eof (^Z) has been received */
  76. int errors;
  77. long Bytesleft;        /* number of bytes of incoming file left */
  78. long Modtime;        /* Unix style mod time for incoming file */
  79. int Filemode;        /* Unix style mode for incoming file */
  80. char Pathname[PATHLEN];
  81. char *Progname;        /* the name by which we were called */
  82.  
  83. int Thisbinary;        /* current file is to be received in bin mode */
  84. int Blklen;        /* record length of received packets */
  85. char Lzmanag;        /* Local file management request */
  86. char zconv;        /* ZMODEM file conversion request */
  87. char zmanag;        /* ZMODEM file management request */
  88. char ztrans;        /* ZMODEM file transport request */
  89.  
  90. jmp_buf tohere;        /* For the interrupt on RX timeout */
  91. jmp_buf abrtjmp;    /* for force abort */
  92. jmp_buf busjmp;        /* for bus errors */
  93. jmp_buf addrjmp;    /* for address errors */
  94. unsigned long BusErr, AddrErr;    /* saved vector addresses */
  95. int Zctlesc;        /* Encode control characters */
  96. int SendType;        /* Which send line to use    */
  97. int Modem;        /* Send using Xmodem */
  98. int lsct;
  99. int tryzhdrtype;    /* Header type to send corresponding to Last rx close */
  100. int Txfcs32;        /* TRUE means send binary frames with 32 bit FCS */
  101.  
  102.     /* Globals used by ZMODEM functions */
  103. int Rxframeind;        /* ZBIN or ZHEX indicates type of frame received */
  104. int Rxtype;        /* Type of header received */
  105. int Rxcount;        /* Count of data bytes received */
  106. int Rxtimeout;        /* Tenths of seconds to wait for something */
  107. int Znulls;        /* Number of nulls to send at beginning of ZDATA hdr */
  108. char Rxhdr[4];        /* Received header */
  109. char Txhdr[4];        /* Transmitted header */
  110. long Rxpos;        /* Received file position */
  111. long Txpos;        /* Transmitted file position */
  112. char Attn[ZATTNLEN+1];    /* Attention string rx sends to tx on err */
  113.  
  114.         /* Globals used by Sz */
  115. char Lzconv;    /* Local ZMODEM file conversion request */
  116. char Lztrans;
  117. char *Cmdstr;        /* Pointer to the command string */
  118. int Optiong;        /* Let it rip no wait for sector ACK's */
  119. int Noeofseen;
  120. int Totsecs;        /* total number of sectors this file */
  121. int Command;        /* Send a command, then exit. */
  122. int Cmdack1;        /* Rx ACKs command, then do it */
  123. int Exitcode;
  124. int Testattn;        /* Force receiver to send Attn, etc with qbf. */
  125. int Lastc;        /* Count of last buffer read or -1 */
  126. int Dontread;        /* Don't read the buffer, it's still there */
  127. int Wantfcs32;        /* want to send 32 bit FCS */
  128. long Lastread;        /* Beginning offset of last buffer read */
  129. jmp_buf intrjmp;    /* For the interrupt on RX CAN */
  130.  
  131. char *qbf;
  132. unsigned int Rxbuflen;    /* Receiver's max buffer length */
  133. int Cmdtries;
  134. int Filcnt;        /* count of number of files opened */
  135. int Lfseen;
  136. int Tframlen;        /* Override for tx frame length */
  137. int blkopt;        /* Override value for zmodem blklen */
  138. int Rxflags;
  139. int Ascii;        /* Add CR's for brain damaged programs */
  140. int Fullname;        /* transmit full pathname */
  141. int Unlinkafter;    /* Unlink file after it is sent */
  142. int Dottoslash;        /* Change foo.bar.baz to foo/bar/baz */
  143. int errcnt;        /* number of files unreadable */
  144. int siggi;        /* line interrupt enable flag     */
  145.  
  146. /* crctab calculated by Mark G. Mendel, Network Systems Corporation */
  147. unsigned int crctab[256] = {
  148.     0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
  149.     0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
  150.     0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
  151.     0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
  152.     0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
  153.     0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
  154.     0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
  155.     0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
  156.     0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
  157.     0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
  158.     0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
  159.     0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
  160.     0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
  161.     0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
  162.     0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
  163.     0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
  164.     0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
  165.     0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
  166.     0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
  167.     0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
  168.     0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
  169.     0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
  170.     0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
  171.     0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
  172.     0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
  173.     0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
  174.     0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
  175.     0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
  176.     0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
  177.     0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
  178.     0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
  179.     0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
  180. };
  181.  
  182. /*
  183.  * Copyright (C) 1986 Gary S. Brown.  You may use this program, or
  184.  * code or tables extracted from it, as desired without restriction.
  185.  *
  186.  *   Need an unsigned type capable of holding 32 bits;
  187.  */
  188. typedef unsigned long int UNS_32_BITS;
  189.  
  190. /* First, the polynomial itself and its table of feedback terms.  The  */
  191. /* polynomial is                                                       */
  192. /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
  193. /* Note that we take it "backwards" and put the highest-order term in  */
  194. /* the lowest-order bit.  The X^32 term is "implied"; the LSB is the   */
  195. /* X^31 term, etc.  The X^0 term (usually shown as "+1") results in    */
  196. /* the MSB being 1.                                                    */
  197.  
  198. /* Note that the usual hardware shift register implementation, which   */
  199. /* is what we're using (we're merely optimizing it by doing eight-bit  */
  200. /* chunks at a time) shifts bits into the lowest-order term.  In our   */
  201. /* implementation, that means shifting towards the right.  Why do we   */
  202. /* do it this way?  Because the calculated CRC must be transmitted in  */
  203. /* order from highest-order term to lowest-order term.  UARTs transmit */
  204. /* characters in order from LSB to MSB.  By storing the CRC this way,  */
  205. /* we hand it to the UART in the order low-byte to high-byte; the UART */
  206. /* sends each low-bit to hight-bit; and the result is transmission bit */
  207. /* by bit from highest- to lowest-order term without requiring any bit */
  208. /* shuffling on our part.  Reception works similarly.                  */
  209.  
  210. /* The feedback terms table consists of 256, 32-bit entries.  Notes:   */
  211. /*                                                                     */
  212. /*     The table can be generated at runtime if desired; code to do so */
  213. /*     is shown later.  It might not be obvious, but the feedback      */
  214. /*     terms simply represent the results of eight shift/xor opera-    */
  215. /*     tions for all combinations of data and CRC register values.     */
  216. /*                                                                     */
  217. /*     The values must be right-shifted by eight bits by the "updcrc"  */
  218. /*     logic; the shift must be unsigned (bring in zeroes).  On some   */
  219. /*     hardware you could probably optimize the shift in assembler by  */
  220. /*     using byte-swap instructions.                                   */
  221.  
  222. unsigned long int crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
  223.     0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
  224.     0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 
  225.     0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
  226.     0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 
  227.     0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  228.     0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 
  229.     0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
  230.     0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 
  231.     0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
  232.     0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 
  233.     0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
  234.     0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 
  235.     0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
  236.     0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 
  237.     0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  238.     0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 
  239.     0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
  240.     0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 
  241.     0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
  242.     0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 
  243.     0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
  244.     0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 
  245.     0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
  246.     0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 
  247.     0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  248.     0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 
  249.     0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
  250.     0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 
  251.     0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
  252.     0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 
  253.     0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
  254.     0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 
  255.     0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
  256.     0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 
  257.     0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  258.     0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 
  259.     0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
  260.     0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 
  261.     0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
  262.     0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 
  263.     0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
  264.     0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 
  265.     0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
  266.     0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 
  267.     0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  268.     0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 
  269.     0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
  270.     0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 
  271.     0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
  272.     0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 
  273.     0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
  274.     0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 
  275.     0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
  276.     0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 
  277.     0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  278.     0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 
  279.     0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
  280.     0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 
  281.     0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
  282.     0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 
  283.     0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 
  284.     0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 
  285.     0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 
  286.     0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL 
  287. }; 
  288.  
  289. #ifndef REMOTE
  290. int *aline_addr;        /* Base addr of aline variables */
  291. #endif
  292.  
  293. int hlines = 25;        /* # of lines on screen        */
  294. int rez;            /* current resolution        */
  295. int scolor = 0;            /* current fg/bg screen color toggle */
  296.  
  297. #ifndef REMOTE
  298. long *ms_ptr;            /* Pointer to my screen memory, aligned at
  299.                    a 256 bytes boundary */
  300. #endif /* REMOTE */
  301.  
  302. #if (!(MWC || MANX))
  303. #ifndef REMOTE
  304. long m_screen[8*1024+32];    /* My screen memory
  305.                    32K bytes + 256 Bytes guard for alignement
  306.                    In the worst case when we align we have to
  307.                    go 255 bytes from &m_screen[0], hence the
  308.                    256 Byte guard is required */
  309. #endif /* REMOTE */
  310.  
  311. #else /* MWC || MANX */
  312.  
  313. #ifdef RECURSE
  314. #ifdef BIGSTACK
  315. #ifdef MWC
  316. long _stksize = 128L * 1024L;
  317. #else
  318. long _STKSIZ = 128L * 1024L;
  319. #endif
  320. #else
  321. #ifdef MWC
  322. long _stksize = 16L * 1024L;
  323. #else
  324. long _STKSIZ = 16L * 1024L;
  325. #endif
  326. #endif /* BIGSTACK */
  327. #else
  328. #ifdef MWC
  329. long _stksize = 16384L;
  330. #else
  331. long _STKSIZ = 16384L;
  332. #endif
  333. #endif /* RECURSE */
  334.  
  335. #ifndef REMOTE
  336. long *m_screen;            /* Presently Mark Willams will not allow
  337.                    > 32K static structures */
  338. #endif /* REMOTE */
  339.  
  340. #endif /* MWC */
  341.  
  342. #ifdef DLIBS
  343. #ifdef RECURSE
  344. #ifdef BIGSTACK
  345. long _STKSIZE = 128L * 1024L;
  346. #else
  347. long _STKSIZE = 16L * 1024L;
  348. #endif /* BIGSTACK */
  349. #else
  350. long _STKSIZE = 16384L;
  351. #endif /* RECURSE */
  352. #endif /* DLIBS */
  353.  
  354. struct stat statbuf;          /* Disk Transfer address for Find first etc */
  355. int Baudrate;              /* Current baud rate                  */
  356. long drv_map;              /* bit vector of valid drives */
  357.  
  358. BAUDS vbauds[] = {
  359.     { "19200", 0, 19200 },
  360.     { "9600" , 1,  9600 },
  361.     { "4800" , 2,  4800 },
  362.     { "4800" , 2,  4800 },
  363.     { "2400" , 4,  2400 },
  364.     { "2400" , 4,  2400 },
  365.     { "2400" , 4,  2400 },
  366.     { "1200" , 7,  1200 },
  367.     { "1200" , 7,  1200 },
  368.     { "300"  , 9,   300 },
  369.     { (char *)NULL, -1, -1 }
  370. };
  371.  
  372. IOREC save,    /* the original Iorec is saved here for the duration of this
  373.            process */
  374.       *savep;    /* ptr returned by Iorec() */
  375.  
  376. char iobuf[IBUFSIZ]; /* My large Rs232 receive buffer */
  377.  
  378. #ifdef DYNABUF
  379. long BBUFSIZ;
  380. #endif /* DYNABUF */
  381.  
  382. extern long pr_time;
  383.  
  384.         /* statics */ 
  385. static char *tsr_ptr = (char *)0x00fffa2dL; /* See St internals */
  386. static long *hz_200 =  (long *)0x000004ba; /* Yes the Hitch Hikers */
  387.                        /* Guide is wrong!! */
  388.  
  389. static long 
  390.      alrm_time = 0L;      /* Time of next timeout (200 Hz) */ 
  391.  
  392. static char *special[] = { 
  393. ".PRG", ".TOS", ".TTP", ".ARC", ".ACC", ".IMG", ".RSC", ".O",
  394. ".OBJ", ".NEO", 
  395. ".PIC", ".PI1", ".PI2", ".PI3", ".PQ1", ".PQ2", ".PQ3", ".BRD",
  396. ".ANI", ".STW", 
  397. ".FNT", ".PRT", ".SNG", ".NEC", ".CNF", ".Z"  , ".DFN", ".GEM",
  398. ".EZD", ".LNK", 
  399. ".SYM", ".DVI", ".PIX", ".X32", ".OUT", ".A",   ".CCC", ".CL",
  400. ".CMD", ".COM", 
  401. ".CRL", ".DAT", ".DIR", ".EXE", ".OVL", ".PAG", ".REL", ".SAV",
  402. ".SUB", ".SWP", 
  403. ".SYS", ".TAR", ".UTL", ".BIN", ".LBR", ".IM",  ".PAK",
  404. ".SBM", ".OBM", ".DIC", ".NDX", ".TFM", ".PBM", ".PBP", ".PCC",
  405. ".PXL",
  406. "" 
  407. }; 
  408.  
  409. /* 
  410.  * mode(n) 
  411.  *  2: set a cbreak, XON/XOFF control mode if using Pro-YAM's -g
  412.  option 
  413.  *  1: save old tty stat, set raw mode  
  414.  *  0: restore original tty mode 
  415.  */
  416. mode(n)
  417. {
  418.  
  419.     vfile("mode:%d", n);
  420.     switch(n) {
  421.  
  422.     case 2:    /* Cbreak mode used by sb when -g detected */
  423.         return OK;
  424.     case 1:
  425.         return OK;
  426.     case 0:
  427.         while(Bconstat(1)) Bconin(1);    /* flush input              */
  428.  
  429.         return OK;
  430.     default:
  431.         return ERROR;
  432.     }
  433. }
  434.  
  435. /*
  436.  * send a break
  437.  * Modifies Bit 3 in the TSR (reg 23) of the Mfp
  438.  */
  439.  
  440. sendbrk()
  441. {
  442.     register long save_ssp;
  443.     register long time;
  444.  
  445.     save_ssp = Super(0L);    /* Super Mode */
  446.  
  447.     /* set bit 3 of the TSR */
  448.     *tsr_ptr |= (char)8;
  449.  
  450.     
  451.     /* wait for 250 ms */
  452.     time = *hz_200 + 50;
  453.     while(*hz_200 < time)
  454.         /* wait */ ;
  455.  
  456.     /* reset bit 3 of the tsr */
  457.     *tsr_ptr &= (char)~8;
  458.  
  459.     Super(save_ssp);    /* Back to user Mode */
  460. }
  461.  
  462. #ifdef TX
  463. /*
  464.  * Put transmit section of the MFP uart off
  465.  *
  466.  */
  467. Txoff()
  468. {
  469.     register long save_ssp;
  470.  
  471.     save_ssp = Super(0L);    /* Super Mode */
  472.     
  473.     /* clear bit 0 of the tsr */
  474.     *tsr_ptr &= (char)~1;
  475.  
  476.     Super(save_ssp);    /* Back to user Mode */
  477. }
  478.  
  479. /*
  480.  * Put transmit section of the MFP uart on
  481.  *
  482.  */
  483. Txon()
  484. {
  485.     register long save_ssp;
  486.  
  487.     save_ssp = Super(0L);    /* Super Mode */
  488.     
  489.     /* set bit 0 of the tsr */
  490.     *tsr_ptr |= (char)1;
  491.  
  492.     Super(save_ssp);    /* Back to user Mode */
  493. }
  494. #endif /* TX */
  495.  
  496.  
  497. /*
  498.  * read_modem() - read upto count characters from the modem port
  499.  * Check for user abort (^C) and timeout at the same time
  500.  */
  501. int read_modem(buf, count)
  502. register char *buf;
  503. register int count;
  504. {
  505.     register int n;
  506.     extern void rd_time();
  507.  
  508.     n = 0;
  509.  
  510.     while(1)
  511.     {
  512. #ifndef REMOTE
  513.         if(Bconstat(2))
  514.         {
  515.             /* Character Hit at the Keyboard - is it ^C */
  516.             if((Bconin(2) & 0x7f) == CTRL('C'))
  517.             {
  518.                 /* It is a Control-C */
  519.                 if(SendType)
  520.                     bibis(3);
  521.                 else
  522.                     bibi(3);
  523.             }
  524.             
  525.         }
  526. #endif
  527.         if(Bconstat(1))
  528.         {
  529.             /* Character available at Modem Port */
  530.             n++;
  531.             *buf++ = Bconin(1);
  532.  
  533.             while((n < count)  && Bconstat(1))
  534.             {
  535.                 *buf++ = Bconin(1);
  536.                 n++;
  537.  
  538.             }
  539.             return n;
  540.         }
  541.         
  542.         /* Check for time out if required */
  543.         if(alrm_time != 0)
  544.         {
  545.             /* Alarm Set */
  546.             Supexec(rd_time);
  547.             if(pr_time >= alrm_time)
  548.                 /* timeout */
  549.                 longjmp(tohere, -1);
  550.         }
  551.     }
  552. }
  553.  
  554.  
  555. /*
  556.  * alarm() - set the alarm time
  557.  */
  558. void stalarm(n)
  559. unsigned int n;
  560. {
  561.     extern void rd_time();
  562.  
  563.     if(n > 0)
  564.     {
  565.         Supexec(rd_time);
  566.         /* We really need n * 200 but n * 256 is close enough */
  567.         alrm_time = pr_time + ( n << 8 );
  568.     }
  569.     else
  570.         alrm_time = 0L;
  571. }
  572.  
  573. /*
  574.  * write_modem() - send buffer to the modem port
  575.  *
  576. */
  577. void write_modem(buf,len)
  578. register char *buf;
  579. register int len;
  580. {
  581.     register int i;
  582.     for(i = 0; i < len; i++)
  583.            Bconout(1, *buf++);
  584. }
  585.  
  586.  
  587. /*
  588.  * flushinput() - flush any characters in the modem port
  589.  * a future enhancement may be flush any characters that are in there
  590.  * and any that come in over the next 1 second -- Ymodem does that
  591.  *
  592.  */
  593. void flushinput()
  594. {
  595.     while(Bconstat(1))
  596.         Bconin(1);
  597. }
  598.  
  599.  
  600.  
  601. int isbinary(name)
  602. register char *name;
  603. {
  604.     register char **p;
  605.     register char *ext;
  606.     extern char *rindex();
  607.     extern int ustrcmp();
  608.     
  609.     if((ext = rindex(name,'.')) == (char *)NULL)
  610.     {
  611.         return 0;
  612.     }
  613.     
  614.     for(p = special; **p != '\0'; p++)
  615.         if(ustrcmp(ext,*p) == 0)
  616.         return 1;
  617.     return 0;
  618. }
  619.  
  620. #define upper(X) (islower(X)?toupper(X):X)
  621.  
  622. /* Strcmp - case insensative */
  623. int ustrcmp(s1,s2)
  624. register char *s1, *s2;
  625. {
  626.     while(*s1 != '\0')
  627.     {
  628.         if(*s2 == '\0')
  629.             return 1;
  630.         if(upper(*s1) != *s2)
  631.             return 1;
  632.         s1++;
  633.         s2++;
  634.     }
  635.     if(*s2 != '\0')
  636.         return 1;
  637.     else
  638.         return 0;
  639. }
  640.  
  641.  
  642. /*
  643.  * Ensure that each subdirectory in the pathname exists.
  644.  * If one doesn'nt, make the rest of the directory
  645.  * Returns ERROR if it has trouble creating a path
  646.  *
  647.  */
  648. int pathensure(name)
  649. char *name;
  650. {
  651.     extern char *index();
  652.  
  653.     if(index(name, '\\') == (char *)NULL)
  654.         /* nothing to check */
  655.         return OK;
  656.  
  657.     return pathrest(name, (char *)NULL);
  658. }
  659.  
  660. /*
  661.  * check rest of the path recursively
  662.  *    If any component of the path name is longer than 8/12 characters then
  663.  *    warn.
  664.  *
  665.  */
  666. int pathrest(name, prev)
  667. char *name, *prev;
  668. {
  669.     char previous[128];
  670.     char component[13];
  671.     register char *p, *q, *r, *s;
  672.     register int warn;
  673.     extern char *index();
  674.     extern char *in();
  675.  
  676.     if((r = index(name, '\\')) == (char *)NULL)
  677.         /* nothing more to check */
  678.         return OK;
  679.  
  680.     /* pick up the next component of the path name, 8/12 chars max for ST */
  681.     warn = 0;
  682.     if((s = in(name, r, '.')) == (char *)NULL)
  683.     {
  684.         /* component does'nt contain a dot */
  685.         if( ((long)r - (long)name) > 8)
  686.         {
  687.             warn++;
  688.             strncpy(component, name, 8);
  689.             q = &component[8];
  690.         }
  691.         else
  692.         {
  693.             register int n;
  694.  
  695.             n = (int)((long)r - (long)name);
  696.             strncpy(component, name, n);
  697.             component[n] = '\0';
  698.             q = &component[(strlen(component))];
  699.         }
  700.     }
  701.     else
  702.     {
  703.         /* component contains a dot */
  704.         if(((long)s - (long)name) > 8)
  705.         {
  706.             warn++;
  707.             strncpy(component, name, 8);
  708.             q = &component[8];
  709.         }
  710.         else
  711.         {
  712.             for(p = name, q = component; p != s; )
  713.                 *q++ = *p++;
  714.         }
  715.         *q++ = '.';
  716.         s++;
  717.         if(s != r)
  718.         {
  719.             if(((long)r - (long)s) > 3)
  720.             {
  721.                 warn++;
  722.                 strncpy(q, s, 3);
  723.                 q = &q[3];
  724.             }
  725.             else
  726.             {
  727.                 for(p = s; p != r; )
  728.                     *q++ = *p++;
  729.             }
  730.         }
  731.     }
  732.     *q = '\0';
  733.  
  734. #ifndef REMOTE
  735.     if(warn)
  736.     {
  737.         fprintf(stderr,
  738.         "?WARNING - A component of the path is longer than 8/12 chars\n");
  739.         fprintf(stderr,"%s --> %s\n", name, component);
  740.     }
  741. #endif
  742.     if(prev == (char *)NULL)
  743.         strcpy(previous, component);
  744.     else
  745.     {
  746.         strcpy(previous, prev);
  747.         strcat(previous, "\\");
  748.         strcat(previous, component);        
  749.     }
  750.  
  751.     if(existd(previous))
  752.         /* it exists - go do rest */
  753.         return pathrest(++r, previous);
  754.  
  755.     /* does not exist,                 */
  756.     /* make this component and all its children */
  757.     return makesubtree(++r, previous);
  758. }
  759.  
  760. /*
  761.  * make a subtree
  762.  */
  763. int makesubtree(name, prev)
  764. char *name, *prev;
  765. {
  766.     char previous[128];
  767.     char component[13];
  768.     register char *p, *q, *r, *s;
  769.     register int warn;
  770.     extern char *index();
  771.     extern char *in();
  772.  
  773.     if(Dcreate(prev) != 0)
  774.     {
  775.         log2("Trouble trying to create subtree\n");
  776.         fprintf(STDERR,"%s\n", prev);
  777.         return ERROR;
  778.     }
  779. #ifndef REMOTE
  780.     fprintf(stderr,"Created Directory %s\n", prev);
  781. #endif
  782.     if((r = index(name, '\\')) == (char *)NULL)
  783.         /* nothing more to do */
  784.         return OK;
  785.  
  786.     /* pick up the next component of the path name, 8/12 chars max for ST */
  787.     warn = 0;
  788.     if((s = in(name, r, '.')) == (char *)NULL)
  789.     {
  790.         /* component does'nt contain a dot */
  791.         if( ((long)r - (long)name) > 8)
  792.         {
  793.             warn++;
  794.             strncpy(component, name, 8);
  795.             q = &component[8];
  796.         }
  797.         else
  798.         {
  799.             register int n;
  800.  
  801.             n = (int)((long)r - (long)name);
  802.             strncpy(component, name, n);
  803.             component[n] = '\0';
  804.             q = &component[(strlen(component))];
  805.         }
  806.     }
  807.     else
  808.     {
  809.         /* component contains a dot */
  810.         if(((long)s - (long)name) > 8)
  811.         {
  812.             warn++;
  813.             strncpy(component, name, 8);
  814.             q = &component[8];
  815.         }
  816.         else
  817.         {
  818.             for(p = name, q = component; p != s; )
  819.                 *q++ = *p++;
  820.         }
  821.         *q++ = '.';
  822.         s++;
  823.         if(s != r)
  824.         {
  825.             if(((long)r - (long)s) > 3)
  826.             {
  827.                 warn++;
  828.                 strncpy(q, s, 3);
  829.                 q = &q[3];
  830.             }
  831.             else
  832.             {
  833.                 for(p = s; p != r; )
  834.                     *q++ = *p++;
  835.             }
  836.         }
  837.     }
  838.     *q = '\0';
  839.  
  840. #ifndef REMOTE
  841.     if(warn)
  842.     {
  843.         fprintf(stderr,
  844.         "?WARNING - A component of the path is longer than 8/12 chars\n");
  845.         fprintf(stderr,"%s --> %s\n", name, component);
  846.     }
  847. #endif
  848.     strcpy(previous, prev);
  849.     strcat(previous, "\\");
  850.     strcat(previous, component);        
  851.  
  852.  
  853.  
  854.     /* go do the rest of them */
  855.     return makesubtree(++r, previous);
  856. }
  857.  
  858.  
  859. /*
  860.  * test if a subdirectory exists
  861.  * include special case of 'D:\' that Fsfirst does'nt handle correctly
  862.  */
  863. int existd(name)
  864. register char *name;
  865. {
  866.     /* assuming the DTA buffer is already set up */
  867.     extern long drv_map;
  868.     extern struct stat statbuf;
  869.     register int drive;
  870.     
  871.     if (Fsfirst(name , 0x0021|0x0010) == 0)
  872.     {
  873.         if((statbuf.st_mode & 0x0010) == 0x0010)
  874.             return TRUE;
  875.     }
  876.  
  877.     /* Gemdos doesn't like d:\ style dirs */
  878.     if((name[3] == '\0') && (name[2] == '\\') && (name[1] == ':'))
  879.     {
  880.         drive = name[0];
  881.         if(isupper(drive))
  882.             drive = tolower(drive);
  883.  
  884.         drive = drive - 'a';
  885.         if((drv_map & (1L << drive)) == 0)
  886.             return FALSE;
  887.         else
  888.             return TRUE;
  889.     }
  890.     /* Nor does Gemdos understand '.' or '..' */
  891.     /* Hey Atari, don't you guys ever test anything */
  892.     if((strcmp(name,".") == 0) || (strcmp(name,"..") == 0) ||
  893.        (strcmp(name,".\\") == 0) || (strcmp(name,"..\\") == 0))
  894.         return TRUE;
  895.  
  896.     return FALSE;
  897. }
  898.  
  899. /*
  900.  * Does a file exist
  901.  */
  902. int existf(name)
  903. register char *name;
  904. {
  905.     /* assuming the DTA buffer is already set up */
  906.     
  907.     return (Fsfirst(name , 0x0001) == 0);
  908.  
  909. }
  910.  
  911. /*
  912.  * stsystem(cmd) - execute a process
  913.  * char *cmd;   command to execute (including redirections etc)
  914.  */
  915. int stsystem(cmd)
  916. char *cmd;
  917. {
  918.         register char *ptr1;             /* general pointers */
  919.         register char save;              /* */
  920.         register int status;            /* return status       */
  921.         register char *args;            /* arguments            */
  922.         register int len;               /* length of args - 2   */
  923.         char nils[2];
  924.         extern char *malloc();
  925.  
  926.  
  927.         nils[0] = nils[1] = '\0';
  928.         for(ptr1 = cmd; (!isspace(*ptr1)) && (*ptr1 != '\0'); ptr1++)
  929.                 /* skip till end of path name */;
  930.         if(*ptr1 != '\0')
  931.         {
  932.                 /* cmd does have a command tail */
  933.                 /* save the char at the position and terminate the path */
  934.                 save = *ptr1;
  935.                 *ptr1++ = '\0'; /* command tail is the rest of it */
  936.  
  937.                 if((args = (char *) malloc((len = strlen(ptr1)) + 2))
  938.                     == (char *)NULL)
  939.                 {
  940.                         /* could not allocate memory */
  941.                         return(-1);
  942.                 }
  943.                 *args++ = len;
  944.                 strcpy(args,ptr1);
  945.                 args--;
  946.                 /* now do the load and go */
  947.                 status = Pexec(0,cmd,args,(char *)NULL);
  948.                 /* restore cmd to original state */
  949.                 *--ptr1 = save;
  950.                 free(args);
  951.         }
  952.         else
  953.         {
  954.                 /* command does not have a tail */
  955.  
  956.                 /* now do the load and go */
  957.                 status = Pexec(0,cmd,nils,(char *)NULL);
  958.         }
  959.  
  960.         return(status);
  961. }
  962.  
  963. stsleep(n)
  964. int n;
  965. {
  966.     extern void rd_time();
  967.  
  968.     if(n != 0)
  969.     {
  970.         Supexec(rd_time);
  971.         /* We really need n * 200 but n * 256 if close enough */
  972.         alrm_time = pr_time + ( n << 8 );
  973.  
  974.         while(alrm_time > pr_time)
  975.         {
  976.             Supexec(rd_time);
  977.         }
  978.         alrm_time = 0L;
  979.     }
  980. }
  981.  
  982.  
  983. initz()
  984. {
  985.      Zmodem=0;        /* ZMODEM protocol requested */
  986.      Nozmodem = 0;        /* If invoked as "rb" */
  987.      Badclose = 0;        /* Error on last close */
  988.      Batch=0;
  989.      Wcsmask=0377;
  990.      Verbose=0;
  991.      lsct = 1;
  992.      Quiet=0;        /* overrides logic that would otherwise set verbose */
  993.      Lleft=0;        /* number of characters in linbuf */
  994.  
  995.      logf = (FILE *)NULL;
  996.      vdebug = 0;
  997.  
  998.      Readnum = KSIZE;    /* Number of bytes to ask for in read() from modem */
  999.      Crcflg = FALSE;
  1000.      fout = (-1);
  1001.      errors = 0;
  1002.      Rxtimeout = 100;    /* Tenths of seconds to wait for something */
  1003.      Modem = 0;
  1004.      Blklen = SECSIZ;    /* record length of received packets */
  1005.  
  1006.     qbf="The quick brown fox jumped over the lazy dog's back 1234567890\r\n";
  1007.     Cmdtries = 11;
  1008.     Filcnt=0;        /* count of number of files opened */
  1009.     Lfseen=0;
  1010.     Rxbuflen = 1024;    /* Receiver's max buffer length */
  1011.     Tframlen = 0;        /* Override for tx frame length */
  1012.     blkopt=0;        /* Override value for zmodem blklen */
  1013.     Rxflags = 0;
  1014.     Ascii=0;        /* Add CR's for brain damaged programs */
  1015.     Fullname=0;        /* transmit full pathname */
  1016.     Unlinkafter=0;        /* Unlink file after it is sent */
  1017.     Dottoslash=0;        /* Change foo.bar.baz to foo/bar/baz */
  1018.     errcnt=0;        /* number of files unreadable */
  1019.     Testattn = FALSE;
  1020.     siggi = 0;
  1021.     Command = FALSE;
  1022.     Wantfcs32 = TRUE;    /* want to send 32 bit FCS */
  1023.     Znulls = 0;
  1024.     tryzhdrtype=ZRINIT;    /* Header type to send corresponding to Last rx close */
  1025.     Txfcs32 = FALSE;    /* TRUE means send binary frames with 32 bit FCS */
  1026.     ForceBinary = FALSE;    /* Local force binary override for rz */
  1027.      
  1028. }
  1029.  
  1030. /* abort current session - due to async fault */
  1031. aexit(n)
  1032. int n;
  1033. {
  1034.     longjmp(abrtjmp, n);
  1035. }
  1036.  
  1037. buserr()
  1038. {
  1039.     longjmp(busjmp, -1);
  1040. }
  1041.  
  1042. addrerr()
  1043. {
  1044.     longjmp(addrjmp, -1);
  1045. }
  1046.  
  1047. /*
  1048.  * Local console output simulation
  1049.  */
  1050. bttyout(c)
  1051. {
  1052.     if (Verbose)
  1053. #ifdef REMOTE
  1054.         Bconout(1, c);
  1055. #else
  1056.         putc(c, stderr);
  1057. #endif
  1058. }
  1059.  
  1060. /*
  1061.  *  Send a character to modem.  Small is beautiful.
  1062.  */
  1063. sendline(c)
  1064. int c;
  1065. {
  1066. #ifndef REMOTE
  1067.     if (Verbose>4)
  1068.     {
  1069.         fprintf(stderr, "Sendline: %x\n", c);
  1070.  
  1071.     }
  1072. #endif
  1073.     if (SendType)
  1074.         Bconout(1, c & Wcsmask);
  1075.     else
  1076.         Bconout(1, c);
  1077.  
  1078. }
  1079.  
  1080.  
  1081.  
  1082. /*
  1083.  * substr(string, token) searches for token in string s
  1084.  * returns pointer to token within string if found, NULL otherwise
  1085.  */
  1086. char *
  1087. substr(s, t)
  1088. register char *s;
  1089. char *t;
  1090. {
  1091.     register char *ss,*tt;
  1092.     /* search for first char of token */
  1093.     for (ss=s; *s; s++)
  1094.         if (*s == *t)
  1095.             /* compare token with substring */
  1096.             for (ss=s,tt=t; ;)
  1097.             {
  1098.                 if (*tt == '\0')
  1099.                     return s;
  1100.                 if (*ss++ != *tt++)
  1101.                     break;
  1102.             }
  1103.  
  1104.     return ((char *)NULL);
  1105. }
  1106.  
  1107.  
  1108. /* send cancel string to get the other end to shut up */
  1109. canit()
  1110. {
  1111.     static char canistr[] = {
  1112.      ZPAD,ZPAD,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  1113.     };
  1114.  
  1115.     write_modem(canistr, strlen(canistr));
  1116.     if(!SendType)
  1117.         Lleft=0;    /* Do read next time ... */
  1118.  
  1119. }
  1120.  
  1121.  
  1122. /*
  1123.  *  Debugging information output interface routine
  1124.  */
  1125. /* VARARGS1 */
  1126. vfile(f, a, b, c)
  1127. register char *f;
  1128. int a, b, c;
  1129. {
  1130.     if (Verbose > 3)
  1131.     {    /* verbose 2 is normal for us */
  1132.         fprintf(STDERR, f, a, b, c);
  1133.         fprintf(STDERR, "\n");
  1134.  
  1135.         if(vdebug && (logf != (FILE *)NULL))
  1136.         {
  1137.             fprintf(logf, f, a, b, c);
  1138.             fprintf(logf, "\n");
  1139.             fflush(logf);
  1140.         }
  1141.  
  1142.     }
  1143. }
  1144.  
  1145. /* longs and pointers are not integers */
  1146. /* VARARGS1 */
  1147. vfile2(f, a, b, c)
  1148. long a, b, c;
  1149. register char *f;
  1150. {
  1151.     if (Verbose > 3)
  1152.     {
  1153.         fprintf(STDERR, f, a, b, c);
  1154.         fprintf(STDERR, "\n");
  1155.  
  1156.         if(vdebug && (logf != (FILE *)NULL))
  1157.         {
  1158.             fprintf(logf, f, a, b, c);
  1159.             fprintf(logf, "\n");
  1160.             fflush(logf);
  1161.         }
  1162.  
  1163.     }
  1164. }
  1165.  
  1166. char *in(from, to, c)
  1167. register char *from, *to;
  1168. register int c;
  1169. {
  1170.     for(; from < to; from++)
  1171.     {
  1172.         if(*from == c)
  1173.             return from;
  1174.     }
  1175.     return (char *)NULL;
  1176. }
  1177.  
  1178. /*
  1179.  * SetIoBuf() - Save the systems Rs232 buffer and install my large
  1180.  * Rs232 buffer.
  1181.  *
  1182.  */
  1183. void SetIoBuf()
  1184. {
  1185.     /* Get pointer to Rs232 input record */
  1186.     savep = (IOREC *)Iorec(0);
  1187.     
  1188.     /* Save the info */
  1189.     save.ibuf    = savep->ibuf;
  1190.     save.ibufsiz    = savep->ibufsiz;
  1191.     save.ibufhd    = savep->ibufhd;
  1192.     save.ibuftl    = savep->ibuftl;
  1193.     save.ibuflow    = savep->ibuflow;
  1194.     save.ibufhi    = savep->ibufhi;
  1195.     
  1196.     /* Install my buffer in its place */
  1197.     savep->ibuf        = &iobuf[0];
  1198.     savep->ibufsiz    = IBUFSIZ;
  1199.     savep->ibuflow    = IBUFSIZ/4;
  1200.     savep->ibufhi    = (IBUFSIZ / 4) * 3;
  1201.     savep->ibufhd = savep->ibuftl = 0;
  1202.     
  1203. }
  1204.  
  1205. /*
  1206.  * ResetIoBuf() - Reset the Rs232 buffer to the saved (system's) buffer
  1207.  *
  1208.  */
  1209. void ResetIoBuf()
  1210. {
  1211.     savep->ibuf        = save.ibuf;
  1212.     savep->ibufsiz    = save.ibufsiz;
  1213.     savep->ibuflow    = save.ibuflow;
  1214.     savep->ibufhi    = save.ibufhi;
  1215.     savep->ibufhd    = save.ibufhd;
  1216.     savep->ibuftl    = save.ibuftl;
  1217. }
  1218.  
  1219.  
  1220. flush_modem()
  1221. {
  1222.     while(Bcostat(1) == 0);
  1223. }
  1224.  
  1225.  
  1226.  
  1227. /*
  1228.  * Log an error if verbose
  1229.  */
  1230.  
  1231. /*VARARGS1*/
  1232. log2(s,p,u)
  1233. char *s;
  1234. int p, u;
  1235. {
  1236.     if (!Verbose)
  1237.         return;
  1238.     fprintf(STDERR, "\nerror %d: ", errors);
  1239.     fprintf(STDERR, s, p, u);
  1240.  
  1241. #ifdef RDEBUG
  1242.     if(Verbose > 3)
  1243.     {
  1244.         fprintf(logf, "error %d: ", errors);
  1245.         fprintf(logf, s, p, u);
  1246.     }
  1247. #endif
  1248.  
  1249. }
  1250. /*
  1251.  * This version of readline is reasonably well suited for
  1252.  * reading many characters.
  1253.  * timeout is in tenths of seconds
  1254.  */
  1255. int readline(timeout)
  1256. int timeout;
  1257. {
  1258.     register int n;
  1259.     static char *cdq;    /* pointer for removing chars from linbuf */
  1260.  
  1261.     if (--Lleft >= 0)
  1262.     {
  1263. #ifdef RDEBUG
  1264.         if (Verbose > 8)
  1265.         {
  1266.             fprintf(logf, "%02x ", *cdq&0377);
  1267.         }
  1268. #endif
  1269.  
  1270.         return (*cdq++ & Wcsmask);
  1271.     }
  1272. /*    n = timeout/10; */
  1273.     n = timeout >> 3;  /* close enough for rock and roll - see alarm() */
  1274.     if (n < 2)
  1275.         n = 3;
  1276. #ifdef RDEBUG
  1277.     if (Verbose > 3)
  1278.         fprintf(logf, "Calling read: n=%d ", n);
  1279. #endif
  1280.  
  1281.     if (setjmp(tohere))
  1282.     {
  1283.         Lleft = 0;
  1284. #ifdef RDEBUG
  1285.         if (Verbose>3)
  1286.         {
  1287.             fprintf(STDERR, "Readline:TIMEOUT\n");
  1288.             fprintf(logf, "Readline:TIMEOUT\n");
  1289.  
  1290.         }
  1291. #endif
  1292.         return TIMEOUT;
  1293.     }
  1294.     stalarm(n);
  1295.     Lleft=read_modem(cdq=linbuf, Readnum);
  1296.     stalarm(0);
  1297.  
  1298. #ifdef RDEBUG
  1299.     if (Verbose > 3)
  1300.     {
  1301.         fprintf(logf, "Read returned %d bytes\n", Lleft);
  1302.     }
  1303. #endif
  1304.  
  1305.     if (Lleft < 1)
  1306.         return TIMEOUT;
  1307.     --Lleft;
  1308.  
  1309. #ifdef RDEBUG
  1310.     if (Verbose > 8)
  1311.     {
  1312.         fprintf(logf, "%02x ", *cdq&0377);
  1313.     }
  1314. #endif
  1315.  
  1316.     return (*cdq++ & Wcsmask);
  1317. }
  1318.  
  1319. report(sct)
  1320. int sct;
  1321. {
  1322. #ifndef REMOTE
  1323.     if (Verbose>1)
  1324.         fprintf(STDERR,"%03d%c",sct,sct%10? ' ' : '\r');
  1325. #endif
  1326. }
  1327.  
  1328. lreport(sct)
  1329. long sct;
  1330. {
  1331. #ifndef REMOTE
  1332.     if (Verbose>1)
  1333.         fprintf(STDERR,"%06ld%c",sct,lsct%10? ' ' : '\r');
  1334.     lsct++;
  1335. #endif
  1336. }
  1337.  
  1338.  
  1339. #ifdef DLIBS
  1340. _initargs()
  1341. {
  1342. }
  1343. #endif
  1344.  
  1345. wr_modem(s)
  1346. register char *s;
  1347. {
  1348.     while(*s != '\0')
  1349.         Bconout(1, *s++);
  1350. }
  1351.  
  1352. #ifdef DYNABUF
  1353. unsigned char *dalloc()
  1354. {
  1355.     register long avail;
  1356.  
  1357.     if((avail = (long)Malloc(-1L) - LEAVEALONE) < MINACC)
  1358.         return (unsigned char *)NULL;
  1359.  
  1360.     BBUFSIZ = avail;
  1361.     return (unsigned char *)Malloc(BBUFSIZ);
  1362. }
  1363. #endif /* DYNABUF */
  1364.  
  1365. /* *******************************************************
  1366.     This code courtesy of katzung@laidbak.UUCP
  1367.      -- thank you very much 
  1368.    ******************************************************* */
  1369.  
  1370.  
  1371. /* From laidbak!katzung@Sun.COM Tue Apr 26 19:34:41 1988
  1372. Return-Path: <laidbak!katzung@Sun.COM>
  1373. From: Brian Katzung <laidbak!katzung@Sun.COM>
  1374. To: bammi@mandrill.CES.CWRU.Edu
  1375. Subject: Re:  UW
  1376. */
  1377.  
  1378. #define    MFP    0xFFFFFA01L
  1379. #define    TDDR    36
  1380. #define    hz_200    ((unsigned long *) 0x4BAL)
  1381.  
  1382. /* Baud rates 75 (120) and 50 (80) are not currently decoded. */
  1383. static int    timevals[] = {
  1384.     1,    2,    4,    5,    8,    10,    11,
  1385.     16,    32,    64,    96,    128,    143,    175
  1386. };
  1387.  
  1388.  
  1389. /* load rs232 baud rate, returns -1 if not known */
  1390. int getbaud ()
  1391. {
  1392.     register int    i;
  1393.     int    tv;            /* Timer value */
  1394.     int    maxtv;            /* Maximum timer value */
  1395.     unsigned long    endhz;        /* End of polling period */
  1396.     long    savessp;        /* Old stack pointer */
  1397.  
  1398.     savessp = Super(0L);
  1399.     maxtv = 0;
  1400.     endhz = *hz_200 + 8;
  1401.     while (*hz_200 < endhz)
  1402.     {
  1403.         tv = *((unsigned char *) (MFP + TDDR));
  1404.         if (tv > maxtv)
  1405.             maxtv = tv;
  1406.     }
  1407.     (void) Super(savessp);
  1408.     for (i = sizeof(timevals) / sizeof(timevals[0]);
  1409.       --i >= 0 && timevals[i] != maxtv; );
  1410.     if (i >= 0)
  1411.         return(i);
  1412.     return(-1);
  1413. }
  1414.  
  1415. /* -eof- */
  1416.